﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Input.Touch;


namespace G.XNA.Component
{
    /// <summary>
    /// 这是一个实现 IUpdateable 的游戏组件。
    /// </summary>
    public class Button : DrawableGameComponent, IProcessTouch
    {
        SpriteBatch spriteBatch;
        Texture2D tinyTexture;//1*1像素的Texture2D，用来显示按钮的边框并反转背景
        Vector2 textPosition;//文本的位置
        bool isPressed;
        int? touchId = null;

        public event EventHandler Click;

        public Button(Game game, string text)
            : base(game)
        {
            Text = text;
            BackColor = Color.Black;
        }
        public Color BackColor { get; set; }
        /// <summary>
        /// Button相对于屏幕的位置和尺寸
        /// </summary>
        public Rectangle Destination { set; get; }
        /// <summary>
        /// 按钮文本的字体
        /// </summary>
        public SpriteFont SpriteFont { set; get; }
        /// <summary>
        /// 按钮的显示文本
        /// </summary>
        public string Text { set; get; }

        /// <summary>
        /// 允许游戏组件在开始运行之前执行其所需的任何初始化。
        /// 游戏组件能够在此时查询任何所需服务和加载内容。
        /// </summary>
        public override void Initialize()
        {
            // TODO: 在此处添加初始化代码

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(this.GraphicsDevice);

            tinyTexture = new Texture2D(this.GraphicsDevice, 1, 1);
            tinyTexture.SetData<uint>(new uint[] { Color.White.PackedValue });

            base.LoadContent();
        }
        /// <summary>
        /// 允许游戏组件进行自我更新。
        /// </summary>
        /// <param name="gameTime">提供计时值的快照。</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: 在此处添加更新代码
            if (SpriteFont != null && !String.IsNullOrEmpty(Text))
            {
                Vector2 textSize = SpriteFont.MeasureString(Text);
                textPosition =
                    new Vector2((int)(Destination.Left + (Destination.Width - textSize.X) / 2),
                                (int)(Destination.Top + (Destination.Height - textSize.Y) / 2));
            }
            base.Update(gameTime);
        }

        public bool ProcessTouch(Microsoft.Xna.Framework.Input.Touch.TouchLocation touch)
        {
            bool touchHandled = false;
            bool isInside = Destination.Contains((int)touch.Position.X,
                                                 (int)touch.Position.Y);
            switch (touch.State)
            {
                case TouchLocationState.Pressed:
                    if (isInside)
                    {
                        isPressed = true;
                        touchId = touch.Id;
                        touchHandled = true;
                    }
                    break;

                case TouchLocationState.Moved:
                    if (touchId.HasValue && touchId.Value == touch.Id)
                    {
                        isPressed = isInside;
                        touchHandled = true;
                    }
                    break;

                case TouchLocationState.Released:
                    if (touchId.HasValue && touchId.Value == touch.Id)
                    {
                        if (isInside && Click != null)
                            Click(this, EventArgs.Empty);

                        touchId = null;
                        isPressed = false;
                        touchHandled = true;
                    }
                    break;
            }
            return touchHandled;
        }

        public override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin();

            if (isPressed)
            {
                // 绘制反转的背景
                spriteBatch.Draw(tinyTexture, Destination, Color.White);
            }
            else
            {
                //绘制按钮的边框和背景
                Rectangle rect = Destination;
                //白色边框，黑色内容
                spriteBatch.Draw(tinyTexture, rect, Color.White);
                rect.Inflate(-3, -3);//边框为3像素
                spriteBatch.Draw(tinyTexture, rect, BackColor);
            }

            // 绘制按钮的文字
            if (SpriteFont != null && !String.IsNullOrEmpty(Text))
                spriteBatch.DrawString(SpriteFont, Text, textPosition,
                                       isPressed ? Color.Black : Color.White);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
